/**
 * 嵌入向量生成工具
 * 
 * 用于生成文本的嵌入向量表示
 */

import { getModelSettings } from "./model-settings";

/**
 * 为文本创建嵌入向量
 * @param text 输入文本
 * @returns 嵌入向量数组
 */
export async function createEmbeddings(text: string): Promise<number[]> {
  try {
    // 获取嵌入模型设置
    const modelSettings = await getModelSettings();
    const { embeddingModel } = modelSettings;
    
    // 如果没有文本，返回空数组
    if (!text || text.trim() === '') {
      console.warn("尝试为空文本创建嵌入向量");
      return [];
    }
    
    // 准备请求
    let requestData;
    if (embeddingModel.type === "openai") {
      requestData = {
        model: embeddingModel.model,
        input: text,
      };
    } else {
      // 自定义模型的请求格式
      requestData = {
        model: embeddingModel.model,
        text: text,
      };
    }
    
    // 发送请求
    const response = await fetch(embeddingModel.apiUrl, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${embeddingModel.apiKey}`,
      },
      body: JSON.stringify(requestData),
    });
    
    // 检查响应
    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(`生成嵌入向量失败: ${response.status} ${errorText}`);
    }
    
    // 解析响应
    const data = await response.json();
    
    // 根据模型类型提取嵌入向量
    let embedding: number[] = [];
    
    if (embeddingModel.type === "openai") {
      // OpenAI响应格式
      embedding = data.data[0].embedding;
    } else {
      // 自定义模型响应格式，可能需要调整
      embedding = data.embedding || data.embeddings[0];
    }
    
    // 验证嵌入向量
    if (!embedding || !Array.isArray(embedding) || embedding.length === 0) {
      throw new Error("无效的嵌入向量响应");
    }
    
    return embedding;
  } catch (error) {
    console.error("生成嵌入向量错误:", error);
    throw new Error(`嵌入向量生成失败: ${(error as Error).message}`);
  }
}

/**
 * 计算两个向量之间的余弦相似度
 * @param a 第一个向量
 * @param b 第二个向量
 * @returns 余弦相似度，范围为-1到1
 */
export function calculateCosineSimilarity(a: number[], b: number[]): number {
  // 检查向量长度
  if (a.length !== b.length) {
    throw new Error("向量长度不同，无法计算相似度");
  }
  
  // 计算点积
  let dotProduct = 0;
  let normA = 0;
  let normB = 0;
  
  for (let i = 0; i < a.length; i++) {
    dotProduct += a[i] * b[i];
    normA += a[i] * a[i];
    normB += b[i] * b[i];
  }
  
  normA = Math.sqrt(normA);
  normB = Math.sqrt(normB);
  
  // 避免除以零
  if (normA === 0 || normB === 0) {
    return 0;
  }
  
  // 计算余弦相似度
  return dotProduct / (normA * normB);
} 